package com.spzx.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.spzx.product.domain.Product;
import com.spzx.product.domain.ProductDetails;
import com.spzx.product.domain.ProductSku;
import com.spzx.product.domain.SkuStock;
import com.spzx.product.mapper.ProductDetailsMapper;
import com.spzx.product.mapper.ProductMapper;
import com.spzx.product.mapper.ProductSkuMapper;
import com.spzx.product.mapper.SkuStockMapper;
import com.spzx.product.service.IProductService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品 服务实现类
 * </p>
 *
 * @author Login
 * @since 2025-07-17
 */
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {

    @Autowired
    private ProductSkuMapper productSkuMapper;
    @Autowired
    private SkuStockMapper skuStockMapper;
    @Autowired
    private ProductDetailsMapper productDetailsMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public List<Product> selectProduct(Product product) {

        return baseMapper.selectProduct(product);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertProduct(Product product) {

        baseMapper.insert(product);

        List<ProductSku> productSkuList = product.getProductSkuList();
        for (int i = 0; i < productSkuList.size(); i++) {
            //商品sku列表 productSku
            ProductSku productSku = productSkuList.get(i);
            productSku.setSkuCode(product.getId() + "_" + i);
            productSku.setProductId(product.getId());
            productSku.setSkuName(product.getName() + " " + productSku.getSkuSpec());
            productSku.setStatus(0);
            productSkuMapper.insert(productSku);

            //sku_stock
            SkuStock skuStock = new SkuStock();
            skuStock.setSkuId(productSku.getId());
            skuStock.setTotalNum(productSku.getStockNum());
            skuStock.setLockNum(0);
            skuStock.setAvailableNum(productSku.getStockNum());
            skuStock.setSaleNum(0);
            skuStockMapper.insert(skuStock);
        }
            //product_details
            ProductDetails productDetails = new ProductDetails();
            productDetails.setProductId(product.getId());
            List<String> detailsImageUrlList = product.getDetailsImageUrlList();
            productDetails.setImageUrls(String.join(",", detailsImageUrlList));
            productDetailsMapper.insert(productDetails);

        return 1;

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateStatus(Long id, Integer status) {

        //修改商品状态
        Product product = new Product();
        product.setId(id);
        product.setStatus(status);
        baseMapper.updateById( product);

        //修改商品SKU状态
        LambdaUpdateWrapper<ProductSku> updateWrapperSku = new LambdaUpdateWrapper<>();
        updateWrapperSku
                .eq(ProductSku::getProductId, id)
                .set(ProductSku::getStatus, status);
        productSkuMapper.update(null, updateWrapperSku);

        //更新bitmap
        LambdaQueryWrapper<ProductSku> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(ProductSku::getProductId, id)
                .select(ProductSku::getId);
        List<Object> skuIdList = productSkuMapper.selectObjs(queryWrapper);
        if(status.intValue() == 1){
            for (Object skuId : skuIdList) {
                redisTemplate.opsForValue().setBit("product:sku:ids", (Long)skuId, true);
            }
        }else if(status.intValue() == -1){
            for (Object skuId : skuIdList) {
                redisTemplate.opsForValue().setBit("product:sku:ids", (Long)skuId, false);
            }
        }
        return 1;
    }
    @Transactional(rollbackFor = Exception.class) //事务管理，（一荣俱荣，一损俱损）
    @Override
    public int removeProduct(List<Long> ids) {
        //先删除商品
        baseMapper.deleteBatchIds( ids);

        //删除product_details
        productDetailsMapper.delete(
                new LambdaQueryWrapper<ProductDetails>()
                        .in(ProductDetails::getProductId,ids)
        );

        //todo 查询skuIds(先查询,因为在下边skuId会被删除)
        List<ProductSku> productSkuList = productSkuMapper.selectList(
                new LambdaQueryWrapper<ProductSku>()
                        .in(ProductSku::getProductId, ids)
                        .select(ProductSku::getId)
        );
        //todo 获取productSkuIdList中的id字段，封装到skuIdList中
        productSkuList.stream().map(ProductSku::getId).toList();


        //删除productSku
        productSkuMapper.delete(new LambdaQueryWrapper<ProductSku>()
                .in(ProductSku::getProductId,ids)
        );

        //删除Sku Stock
        skuStockMapper.delete(new LambdaQueryWrapper<SkuStock>()
                .in(SkuStock::getSkuId,ids)
        );
        return 1;
    }
    @Transactional(rollbackFor = Exception.class) //事务管理，（一荣俱荣，一损俱损）
    @Override
    public Product selectProductById(Long id) {

        //查询商品基本信息
        Product product = baseMapper.selectById(id);

        //查询product_sku列表
        List<ProductSku> productSkuList = productSkuMapper.selectList(
                new LambdaQueryWrapper<ProductSku>()
                        .eq(ProductSku::getProductId, id)
        );

        //获取skuIdList // 提取SKU的ID列表
        List<Long> skuIdList = productSkuList.stream().map(ProductSku::getId).toList();
        // 查询SKU的库存信息
        List<SkuStock> skuStockList = skuStockMapper.selectList(
                new LambdaQueryWrapper<SkuStock>()
                        .in(SkuStock::getSkuId, skuIdList)
                        .select(SkuStock::getTotalNum, SkuStock::getSkuId)  //getTotalNum，getSkuId只是存在一起，处理方便
        );

        //将skuStockList中对应的stockNum设置到productSkuList中
        //将skuStockList转换成Map，便于根据SKU ID获取库存数量
        Map<Long, Integer> skuStockMap = skuStockList.stream().collect(Collectors.toMap(SkuStock::getSkuId, SkuStock::getTotalNum));
        //填充productSkuList中的stockNum   // 将库存数量填充到对应的ProductSku对象中
        for (ProductSku productSku : productSkuList) {
            productSku.setStockNum(skuStockMap.get(productSku.getId()));
        }
// 将SKU列表设置回商品对象
        product.setProductSkuList(productSkuList);

        //获取商品详情图片信息
        ProductDetails productDetails = productDetailsMapper.selectOne(
                new LambdaQueryWrapper<ProductDetails>()
                        .eq(ProductDetails::getProductId, product.getId())
        );
// 将图片地址字符串拆分为列表并设置回商品对象
        List<String> stringList = Arrays.asList(productDetails.getImageUrls().split(","));
        product.setDetailsImageUrlList(stringList);
// 返回包含完整信息的商品对象
        return product;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateProduct(Product product) {
        //修改商品信息
        baseMapper.updateById(product);

        List<ProductSku> productSkuList = product.getProductSkuList();
        productSkuList.forEach(productSku -> {
            //修改商品SKU信息
            productSkuMapper.updateById(productSku);

            //修改商品库存
            SkuStock skuStock = skuStockMapper.selectOne(
                    new LambdaQueryWrapper<SkuStock>().eq(SkuStock::getSkuId, productSku.getId())
            );
            skuStock.setTotalNum(productSku.getStockNum());
            int availableNum = skuStock.getTotalNum() - skuStock.getLockNum();
            skuStock.setAvailableNum(availableNum);
            skuStockMapper.updateById(skuStock);
        });

        //修改商品详细信息
        ProductDetails productDetails = productDetailsMapper.selectOne(
                new LambdaQueryWrapper<ProductDetails>().eq(ProductDetails::getProductId, product.getId())
        );
        productDetails.setImageUrls(String.join(",", product.getDetailsImageUrlList()));
        productDetailsMapper.updateById(productDetails);
        return 1;
    }
}
